'use strict';

const SysOperationLogsModel = require('../model/SysOperationLogsModel');
const AdminUserRightsModel = require('../model/AdminUserRightsModel');
const PetRegisterInfoModel = require('../model/PetRegisterInfoModel');
const SysMenusModel = require('../model/SysMenusModel');
const sysOperationLogsModel = new SysOperationLogsModel();
const adminUserRightsModel = new AdminUserRightsModel();
const sysMenusModel = new SysMenusModel();
const petRegisterInfoModel = new PetRegisterInfoModel();
const uuidTool = require('uuid/v4');
const crypto = require('crypto');
const moment = require('moment');
const SysMacAddrService = require('../model/SysMacAddrModel.js');
const sysMacAddrService = new SysMacAddrService();
const dateFormat = {
  YYYYMMDDHHmmss: 'YYYYMMDDHHmmss',
  YYYY_MM_DD_HH_mm_ss: 'YYYY-MM-DD HH:mm:ss',
  YYYYMMDD: 'YYYYMMDD',
  YYYY_MM_DD: 'YYYY-MM-DD',
};

/**
 * 挂在 扩展方法到 ctx对象上
 */
module.exports = {
  moment,
  // 获取UUID 
  getUUID(key) {
    return uuidTool(key, this.app.config.uuid.secret).replace(/-/gi, '');
  },
  // 使用MD5加密字符串
  encryOfMD5(str) {
    const saltPassword = str + ':' + this.app.config.myJwt.secret;
    // 加盐密码的md5值
    const md5 = crypto.createHash('md5');
    return md5.update(saltPassword).digest('hex');
  },
  // 获取年
  getYear(date) {
    if (date) {
      return moment(date).format('YYYY');
    }
    return moment(new Date()).format('YYYY');
  },
  // 获取当前时间
  getDate_YYYY_MM_DD_HH_mm_ss(date) {
    if (date) {
      return moment(date).format(dateFormat.YYYY_MM_DD_HH_mm_ss);
    }
    return moment(new Date()).format(dateFormat.YYYY_MM_DD_HH_mm_ss);
  },
  // 获取当前时间
  getDate_YYYYMMDDHHmmss(date) {
    if (date) {
      return moment(date).format(dateFormat.YYYYMMDDHHmmss);
    }
    return moment(new Date()).format(dateFormat.YYYYMMDDHHmmss);
  },
  async checkUserRightsForFunctionByKey(request, petRegId, dogRegNum) {
    const branchCodes = request.userRights.branchCodes;
    const areaCodes = request.userRights.areaCodes;
    let dogRegInfos = [];
    if (petRegId) {
      dogRegInfos = await petRegisterInfoModel.findPetRegInfoById(this.app, petRegId);
    }
    if (dogRegNum) {
      this.logger.debug('类型：', typeof dogRegNum);
      if (typeof dogRegNum == 'object') {
        dogRegInfos = await petRegisterInfoModel.findPetRegInfoByDogRegNum(this.app, dogRegNum.join(','));
      } else {
        dogRegInfos = await petRegisterInfoModel.findPetRegInfoByDogRegNum(this.app, dogRegNum);
      }
    }
    this.logger.debug('返回数据：', dogRegInfos);
    if (request) {
      let isHave = true;
      for (const dogRegInfo of dogRegInfos) {
        if (branchCodes && branchCodes.indexOf(dogRegInfo.areaCode) < 0) {
          isHave = false;
        }
        if (areaCodes && areaCodes.indexOf(dogRegInfo.areaCode) < 0) {
          isHave = false;
        }
      }
      return isHave;
    }
    return true;
  },
  async wxCheckUserRightsForFunctionByKey(request, petRegId, dogRegNum) {
    const branchCodes = request.userRights.branchCodes;
    const areaCodes = request.userRights.areaCodes;
    let dogRegInfos = [];
    if (petRegId) {
      dogRegInfos = await petRegisterInfoModel.wxFindPetRegInfoById(this.app, petRegId);
    }
    if (dogRegNum) {
      this.logger.debug('类型：', typeof dogRegNum);
      if (typeof dogRegNum == 'object') {
        dogRegInfos = await petRegisterInfoModel.wxFindPetRegInfoByDogRegNum(this.app, dogRegNum.join(','));
      } else {
        dogRegInfos = await petRegisterInfoModel.wxFindPetRegInfoByDogRegNum(this.app, dogRegNum);
      }
    }
    this.logger.debug('返回数据：', dogRegInfos);
    if (request) {
      let isHave = true;
      for (const dogRegInfo of dogRegInfos) {
        if (branchCodes && branchCodes.indexOf(dogRegInfo.areaCode) < 0) {
          isHave = false;
        }
        if (areaCodes && areaCodes.indexOf(dogRegInfo.areaCode) < 0) {
          isHave = false;
        }
      }
      return isHave;
    }
    return true;
  },
  async checkUserRightsForFunction(request) {
    const branchCodes = request.userRights.branchCodes;
    const areaCodes = request.userRights.areaCodes;
    if (request && (branchCodes || areaCodes)) {
      this.logger.debug('校验权限1：', request);
      if (branchCodes.indexOf(request.branchCode) >= 0 || branchCodes.indexOf(request.areaCode) >= 0) {
        return true;
      }
      if (areaCodes.indexOf(request.areaCode) >= 0 || areaCodes.indexOf(request.branchCode) >= 0) {
        return true;
      }
      return false;
    }
    return true;
  },
  // 检查是否需要控制
  async getCheckUserRights(controller) {
    const sysMenus = sysMenusModel.findMenuByController(this.app, controller);
    if (sysMenus && sysMenus.isRights == 1) {
      return true;
    }
    return false;
  },
  async getCheckUserRights2(path, controller) {
    const sysMenus = await sysMenusModel.findAllMenuForIsRights(this.app, path, controller);
    if (sysMenus) {
      return true;
    }
    return false;
  },
  // 获取用户所具有的权限类型
  async getCurUserRightsTypeByController(controller) {
    const response = {};
    const userRights = this.curAdminUser.userRights;
    const branchCode = this.curAdminUser.branchCode.split(',');

    if (!userRights) return null;
    const result = userRights.find(item => item.controller == controller);
    if (!result || !result.userRights) return null;
    response.type = result.userRights;
    if (result.userRights == 4) {
      response.creator = this.curAdminUser.id;
    }
    if (result.userRights == 2 || result.userRights == 3 || result.userRights == 5 || result.userRights == 6) {
      // 是否查询子节点
      let isContainChildNode = 0;
      if (result.userRights == 3 || result.userRights == 6) {
        isContainChildNode = 1;
      }
      // 返回类型 1 返回单位编号 0 返回地区编号
      let resultType = 0;
      if (result.userRights == 2 || result.userRights == 3) {
        resultType = 1;
      }
      const codes = await adminUserRightsModel.getUserAreaCodesOrBranchCodeByBranchCode(this.app, branchCode[branchCode.length - 1], resultType, isContainChildNode);
      
      // 返回单位编号
      if (result.userRights == 2 || result.userRights == 3) response.branchCodes = codes;
      // 返回地区编号
      if (result.userRights == 5 || result.userRights == 6) response.areaCodes = codes;
      
    }
    return response;
  },
  // 填写操作日志
  async writeSysOperationLogs(functionName, type, {
    des = '',
    tableName = '',
    curAdminUser = null
  }) {
    if (this.curAdminUser instanceof Object && this.curAdminUser !== null) curAdminUser = this.curAdminUser;
    // 创建操作日志实体对象
    const {
      id,
      realName
    } = curAdminUser;
    const sysOperationLogs = new sysOperationLogsModel.entity();
    sysOperationLogs.operatorId = id; // 操作这ID
    sysOperationLogs.operatorName = realName; // 操作这姓名
    sysOperationLogs.time = this.getDate_YYYYMMDDHHmmss(); // 操作时间

    sysOperationLogs.functionName = functionName; // 操作功能
    sysOperationLogs.type = type; // 操作类型 增加 删除 修改 查询
    // ['操作者名称']在【'操作时间'】对【'zh表名'】执行【'操作类型'】操作
    if (des.length === 0) {
      const operationTime = this.getDate_YYYY_MM_DD_HH_mm_ss();
      sysOperationLogs.des = `【${realName}】在【${operationTime}】对${tableName}执行${type}操作`; // 操作说明  操作说明
    } else {
      sysOperationLogs.des = des;
    }
    // 插入操作日志
    sysOperationLogsModel.insert(this.app, sysOperationLogs);
  },
  getSystemLogType(key = 'CREATE') {
    const typeMap = {};
    typeMap[typeMap['新增'] = 'CREATE'] = '新增';
    typeMap[typeMap['删除'] = 'DELETE'] = '删除';
    typeMap[typeMap['编辑'] = 'UPDATE'] = '编辑';
    typeMap[typeMap['查询'] = 'QUERY'] = '查询';
    typeMap[typeMap['其他'] = 'OTHER'] = '其他';

    return typeMap[key];
  },
  /*
   * 当前时间+1天,日期查询，
   * 传入的日期格式为： 20190602125954
   */
  async getDatePlus1(val) {
    const reg = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/g;
    const arr = reg.exec(val);
    const date = new Date(arr[1], parseInt(arr[2]) - 1, arr[3], arr[4], arr[5], arr[6]);
    const dateStr = moment(date).format('YYYY/MM/DD HH:mm:ss');
    const result = moment(new Date(dateStr)).add(1, 'day').format(dateFormat.YYYYMMDDHHmmss);
    return result;
  },

  /*
   * 增加年份(+1)
   */
  addyear(val) {
    if (val) {
      return moment(val).add(1, 'y').format(dateFormat.YYYYMMDDHHmmss);
    }
    return moment(new Date()).add(1, 'y').format(dateFormat.YYYYMMDDHHmmss);
  },

  /**
   * 
   * @param {*} card 
   * 判断身份证号码
   */
  isCardNo(card) {
    // 身份证号码为15位或者18位，15位时全为数字，18位前17位为数字，最后一位是校验位，可能为数字或字符X  
    const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
    if (reg.test(card) === false) {
      return false;
    }
  },

  /**
   * 养犬登记号判断
   * @param {*} card 
   * 判断身份证号码
   */
  isdogNum(card) {
    // 身份证号码为15位或者18位，15位时全为数字，18位前17位为数字，最后一位是校验位，可能为数字或字符X  
    const reg = /^\d{6}$/;
    if (reg.test(card) === false) {
      return false;
    }
  },

  /**
   * 
   * @param {*} phone
   * 校验手机号 
   */
  getphone(phone) {
    const data = /(^1[3456789]\d{9}$)|(^(0\d{2,3}\-)?([2-9]\d{6,7})+(\-\d{1,6})?$)/;
    if (data.test(phone) === false) {
      return false;
    }
  },
  /*
   * 
   * @param {*} data 
   * @param {*} format 
   * 给万成龙格式化日期
   */
  getDateFormat(data) {
    if (!data) return;
    const reg = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/g;
    const arr = reg.exec(data);
    const date = new Date(arr[1], parseInt(arr[2]) - 1, arr[3], arr[4], arr[5], arr[6]);
    const result = moment(date).format('YYYY/MM/DD HH:mm:ss');
    return result;
  },

  // 获取年月日
  getYeardate(date) {
    if (date) {
      return moment(date).format('YYYY-MM-DD');
    }
    return moment(new Date()).format('YYYY-MM-DD');
  },
  // 生日转换
  getbirthday(date) {
    if (date) {
      return moment(date).format('YYYY/MM/DD');
    }
    return moment(new Date()).format('YYYY/MM/DD');
  },

  // 时间转换
  gettime(date) {
    if (date) {
      return moment(date).format('YYYY/MM/DD');
    }
    return moment(new Date()).format('YYYY/MM/DD');
  },
  // 时间字符串转换 
  DateUtils_GetDateString(dateStr, frontFormat, afterFormat) {
    if (!frontFormat) frontFormat = dateFormat.YYYYMMDDHHmmss;
    if (!afterFormat) afterFormat = dateFormat.YYYY_MM_DD_HH_mm_ss;
    return moment(dateStr, frontFormat).format(afterFormat);
  },
  // 时间字符串转换 
  DateUtils_GetDate(dateStr, frontFormat) {
    if (!frontFormat) frontFormat = dateFormat.YYYYMMDDHHmmss;
    return moment(dateStr, frontFormat).toDate();
  },
  // 操作日期小时数
  DateUtils_getAddHours(hours, date) {
    if (!date) date = new Date();
    if (!hours) return date;
    return moment(date).add(hours, 'hours').toDate();
  },
  // 操作日期小时数
  DateUtils_getAddHoursStr(hours, date, formatStr) {
    if (!formatStr) formatStr = dateFormat.YYYYMMDDHHmmss;
    return moment(this.DateUtils_getAddHours(hours, date)).format(formatStr);
  },
  // 操作日期天数
  DateUtils_getAddDay(days, date) {
    if (!date) date = new Date();
    if (!days) return date;
    return moment(date).add(days, 'days').toDate();
  },
  // 操作日期天数
  DateUtils_getAddDayStr(days, date, formatStr) {
    if (!formatStr) formatStr = dateFormat.YYYYMMDDHHmmss;
    return moment(this.DateUtils_getAddDay(days, date)).format(formatStr);
  },
  // 操作日期月数
  DateUtils_getAddMonth(months, date) {
    if (!date) date = new Date();
    if (!months) return date;
    return moment(date).add(months, 'months').toDate();
  },
  // 操作日期月数
  DateUtils_getAddMonthStr(months, date, formatStr) {
    if (!formatStr) formatStr = dateFormat.YYYYMMDDHHmmss;
    return moment(this.DateUtils_getAddMonth(months, date)).format(formatStr);
  },
  // 操作日期年数
  DateUtils_getAddYears(years, date) {
    if (!date) date = new Date();
    if (!years) return date;
    return moment(date).add(years, 'years').toDate();
  },
  // 操作日期年数
  DateUtils_getAddYearsStr(years, date, formatStr) {
    if (!formatStr) formatStr = dateFormat.YYYYMMDDHHmmss;
    return moment(this.DateUtils_getAddYears(years, date)).format(formatStr);
  },
  async getAllMacAddr() {
    const result = await sysMacAddrService.findAllMacAddr(this.app);
    let res = [];
    if (result.length > 0) {
      res = result.map(obj => obj.mac_addr);
    }
    return res;
  },
  // 将范围数据补全成数组
  supplementScopeToArray(startNum, endNum) {
    const array = [];
    for (startNum; startNum <= endNum; startNum++) {
      array.push(startNum);
    }
    return array;
  },

};
